home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_misc / tnc1stuf.lzh / TNC1KISS.ASM < prev    next >
Assembly Source File  |  1987-12-31  |  41KB  |  1,156 lines

  1.         opt   pag,lis
  2.         abs
  3.         pag
  4.         ttl   "KISS - raw TNC handler"
  5.  
  6. * KISS - a SLIP handler for the TAPR TNC1
  7. * Written by Marc Kaufman, WB6ECE
  8. *       March 1987
  9. *
  10. * Modified by Gerard J Vandergrinten, PA0GRI.
  11. *       Sept 1987
  12. * Copyright 1987 by Marc Kaufman, WB6ECE
  13. * All rights reserved
  14. *
  15. * Permission granted for noncommercial copying and use
  16. * provided this notice is retained.
  17.  
  18. * Correction History:
  19. *
  20. *       4/17/87 - mtk: Initial Release (1.0)
  21. *       4/19/87 - mtk: Improve handling of timer values that are  a
  22. *                       multiple of 65536 E-clock ticks
  23. *       4/30/87 - mtk: Correct error in format of TNC->Host block
  24. *                       by stuffing '0' before data
  25. *       8/10/87 - gjv: Make selfstart rom version,
  26. *                      Add FEND on start of frame,
  27. *                      Move initialized data to easy modifyable place.
  28. *       8/25/87 - gjv: Fix hdlc xmit state hfcs to complement
  29. *                       data to hdlc chip.
  30. *      12/14/87 - mtk: Receive block sometimes was prefixed by a garbage
  31. *                       byte. Don't start-stop the receiver, exept when
  32. *                       shifting into transmit mode.
  33. *      12/22/87 - gjv: Use second ram from tnc-1 if there. (more bufferring)
  34. *      12/22/87 - gjv: Fix command scanner for FESC sequences.
  35.  
  36. * Refer to Phil Karn's description of KISS for details
  37. *
  38. * The following frame types (Host to TNC) are supported:
  39. *
  40. *       0 Data          - data frame to HDLC channel
  41. *       1 TXDelay       - 0 <= TXDelay  <= 255 (* 10 ms.)
  42. *       2 Peristence    - 255 -> transmit now
  43. *       3 SlotTime      - 0 <= SlotTime <= 255 (* 10 ms.)
  44. *       4 TXTail        - 0 <= TXTail   <= 255 (* 10 ms.)
  45. *       5 HDX/FDX       - 0 = HDX, 1 = FDX
  46. *       6 Speed         -     0 < Speed <=     24 (slow TNC)
  47. *                       - 128+0 < Speed <= 128+48 (fast TNC)
  48. *
  49. *       The Speed parameter sets the HDLC baud rate to (Speed*300) baud.
  50. *       The high order bit (128), if set, indicates that the TNC1 is
  51. *        running with a 2x clock.  Maximum baud rates are 7200 for the slow
  52. *        TNC, and 14400 for the fast TNC.
  53.  
  54. * The following frame types (TNC to Host) are supported:
  55. *
  56. *       0 Data          - data frame from HDLC channel
  57.  
  58. * The normal idle state for the async receiver is "waiting for command"
  59. *  after the trailing FEND from the previous packet.
  60.  
  61. * Hardware addresses
  62.  
  63. ***             6551 UART   setup with speed from $f801
  64.  
  65. acia    equ     $2010           base address
  66. acchar  equ     acia
  67. acstat  equ     acia+1
  68. accmnd  equ     acia+2
  69. acctrl  equ     acia+3
  70.  
  71. as_fram equ     $02             framing error only
  72. as_err  equ     $07             parity, framing, and overrun errors
  73. as_rdr  equ     $08             receive data register full
  74. as_xmt  equ     $10             xmit data register empty
  75. as_irq  equ     $80             acia interrupt request
  76.  
  77. ac_dis  equ     $0a             disable transmitter and receiver, set RTS
  78. ac_enb  equ     $09             enable receiver interrupts, set RTS
  79. ac_xmt  equ     $05             enable transmit and receive interrupts
  80.  
  81. ***             6520 parallel i/o chip -- not used
  82.  
  83. pia     equ     $2020           base address
  84. pra     equ     pia             register A
  85. pcra    equ     pia+1           control A
  86. prb     equ     pia+2           register B
  87. pcrb    equ     pia+3           control B
  88.  
  89. ***             6522 peripheral timer and i/o chip
  90.  
  91. via     equ     $2040           base address
  92. vorb    equ     via             output register B
  93. vora    equ     via+15          output register A, no handshake
  94. vddrb   equ     via+2           data direction register B
  95. vddra   equ     via+3           data direction register A
  96. vtim1cl equ     via+4           low byte of timer 1 counter
  97. vtim1ch equ     via+5           high byte of timer 1 counter
  98. vtim1ll equ     via+6           low byte of timer 1 latch
  99. vtim1lh equ     via+7           high byte of timer 1 latch
  100. vtim2l  equ     via+8           low byte of timer 2
  101. vtim2h  equ     via+9           high byte of timer 2
  102. vacr    equ     via+11          auxiliary control register
  103. vpcr    equ     via+12          peripheral control register
  104. vifr    equ     via+13          interrupt flag register
  105. vier    equ     via+14          interrupt enable register
  106.  
  107. timrc1  equ     vtim1cl         both bytes of timer 1 counter
  108. timrl1  equ     vtim1ll         both bytes of timer 1 latch
  109. timer2  equ     vtim2l          both bytes of timer2 (counter and latch)
  110. v_int   equ     $20             timer2 interrupt bit (clear enable)
  111. vs_int  equ     $a0             timer2 interrupt bit (set enable)
  112. h_reset equ     $ec             reset HDLC chip (via vpcr)
  113. h_oper  equ     $ee             operate HDLC chip (via vpcr)
  114. t_cntl  equ     $c0             timer1=free run, timer2=interval, sr=off
  115.  
  116. ***             WD 1933 HDLC chip equates
  117. ***     IMPORTANT: this chip inverts Address and Data bits!!!
  118.  
  119. hdlc    equ     $2800           base address
  120. hcr1    equ     hdlc+7          control register 1
  121. hcr2    equ     hdlc+6          control register 2
  122. hcr3    equ     hdlc+5          control register 3
  123. hrhr    equ     hdlc+4          receive holding register
  124. hthr    equ     hdlc+3          transmit holding register
  125. hir     equ     hdlc+3          interrupt register
  126. hsr     equ     hdlc+2          status register
  127.  
  128. fflags  equ     $01             cr2 - send flags between frames
  129.  
  130. actrcv  equ     $80             activate receiver
  131. actran  equ     $40             activate transmitter
  132. actdtr  equ     $02             turn on DTR
  133. actptt  equ     $01             activate PTT line (misc. out)
  134.  
  135. txon    equ     actran+actdtr+actptt    preamble and data transmission
  136. rcvon   equ     actrcv+actdtr           receiving
  137. h_data  equ     $00+txon        Transmit commands
  138. h_abort equ     $10+txon
  139. h_flag  equ     $20+txon
  140. h_fcs   equ     $30+txon        (sends fcs + flag)
  141. h_MASK  equ     $cf
  142.  
  143. reom    equ     $80             intreg - receive complete with no error
  144. reomerr equ     $40             intreg - receive with error
  145. xcom    equ     $20             intreg - xmt command complete
  146. xcomerr equ     $10             intreg - xmt error (underrun)
  147. dscchg  equ     $08             intreg - CD line state change
  148. drqi    equ     $04             intreg - input character available
  149. drqo    equ     $02             intreg - output character needed
  150. intrq   equ     $01             intreg - set if any of bits 3-7 are new
  151.  
  152. CD      equ     $40             status - location of CD state bit
  153.  
  154. ram0    equ     $0000           bank 0 ram ($0000 - $1fff)
  155. ram0end equ     ram0+8191       top of bank 0 ram
  156. ram1    equ     $4000           bank 1 ram ($4000 - $5fff)
  157. ram1end equ     ram1+8191       top of bank 1 ram
  158. rom     equ     $e000           top rom    ($e000 - $ffff)
  159.  
  160. FEND    equ     @300            frame end
  161. FESC    equ     @333            frame escape
  162. TFEND   equ     @334            transposed frame end
  163. TFESC   equ     @335            transposed frame escape
  164.  
  165. CCZ     equ     $04             zero flag in CC
  166. CCNZ    equ     $fb             non-zero flag in CC
  167. NOT     equ     $ff             for negations
  168.  
  169. stack   equ     $100            my stack is above debug stack
  170.         org     $100            local data starts at direct page 1
  171.  
  172. ***             Local Variables initialized from rom by startup code
  173.  
  174. p_speed rmb     1               processor speed: 0= 1 Mhz, 1= 2 Mhz
  175. a_speed rmb     1               async speed
  176. h_speed rmb     1               (* 300) baud on hdlc
  177. u_txdly rmb     1               tx start delay (* 10 ms)
  178. u_pers  rmb     1               persistence parameter
  179. u_slot  rmb     1               slot time delay (* 10 ms)
  180. u_tail  rmb     1               tx tail hold time (* 10 ms)
  181.  
  182. c_txdly rmb     2               count value for txdelay
  183. c_slot  rmb     2               count value for slot delay
  184. c_tail  rmb     2               count value for tail delay
  185.  
  186. cdval   rmb     1               last CD status value (CD on)
  187. fxflag  rmb     1               0 = hdx, 1 = fdx
  188. rand    rmb     1               pseudo-random value (0 <= rand <= 255)
  189. savhc   rmb     1               last hdlc command saved here
  190. svhir   rmb     1               HDLC interrupt status saved here
  191. temp    rmb     2
  192. tempih  rmb     1               temp used by interrupt handler only
  193. upper_t rmb     1               upper 8 bits of 24 bit timer
  194. xmtok   rmb     1               xmit flag: 0= rcv, +1= xmit ok, -1= xmit
  195. bdblk   rmb     1               set if current block is "bad"
  196.  
  197. *               interrupt routine state information - initial values set
  198.  
  199. ARCV    rmb     2               acia receiver state
  200. AXMIT   rmb     2               acia transmitter state
  201. HRCV    rmb     2               hdlc receiver state
  202. HXMIT   rmb     2               hdlc transmitter state
  203. TIMACT  rmb     2               timer action state (after counted to zero)
  204.  
  205. *               i/o buffers
  206. *
  207. *       this is a circular buffer system, with the buffer extending from
  208. *       [FIRST] to [LIMIT-1].  IN is the real data in pointer.  When the
  209. *       block is accepted, AIN is updated to the value of IN.
  210.  
  211. FIRST   equ     0               pointer offsets for buffer header
  212. IN      equ     2
  213. AIN     equ     4               accepted data, IN pointer
  214. OUT     equ     6
  215. LIMIT   equ     8
  216.  
  217. cmdsize equ     20              buffer for kiss control commands
  218. command rmb     10              cmdbuf,cmdbuf,cmdbuf,cmdbuf,cmdbuf+cmdsize
  219.  
  220. *       buffer from acia to hdlc
  221. abufh   rmb     10              inbufend,inbufend,inbufend,inbufend,ram0end
  222.  
  223. *       buffer from hdlc to acia
  224. hbufa   rmb     10              inbuffer,inbuffer,inbuffer,inbuffer,inbufend
  225.  
  226. cmdbuf  rmb     cmdsize         command buffer here, others at end of memory
  227. inbuffer        rmb             2049
  228. inbufend        equ             *
  229.         pag
  230.         org     $FFF2           Interrupt vector list
  231. *
  232.         fdb     jswi3
  233.         fdb     jswi2
  234.         fdb     jfirq
  235.         fdb     jirq
  236.         fdb     jswi
  237.         fdb     jnmi
  238.         fdb     main
  239. *
  240.         org     0               Interrupt vector indirect area
  241. iswi3   rmb     2
  242. iswi2   rmb     2
  243. ifirq   rmb     2
  244. iirq    rmb     2
  245. iswi    rmb     2
  246. inmi    rmb     2
  247. *
  248.  
  249.         org     $f800
  250.  
  251. initv2  fcb     0               processor speed: 0= 1 Mhz, 1= 2 Mhz
  252.         fcb     12              async port speed
  253.         fcb     4               (* 300) baud on hdlc
  254.         fcb     30              tx start delay (* 10 ms)
  255.         fcb     64              persistence parameter (p=.25)
  256.         fcb     10              slot time delay (* 10 ms)
  257.         fcb     4               tx tail hold time (* 10 ms)
  258.  
  259.         fdb     0               count value for txdelay
  260.         fdb     0               count value for slot delay
  261.         fdb     0               count value for tail delay
  262.  
  263.         fcb     CD              last CD status value (CD on)
  264.         fcb     0               0 = hdx, 1 = fdx
  265.         fcb     0               pseudo-random value (0 <= rand <= 255)
  266.         fcb     0               last hdlc command saved here
  267.         fcb     0               HDLC interrupt status saved here
  268.         fdb     0
  269.         fcb     0               temp used by interrupt handler only
  270.         fcb     0               upper 8 bits of 24 bit timer
  271.         fcb     0               xmit flag: 0= rcv, +1= xmit ok, -1= xmit
  272.         fcb     0               bad frame flag
  273.  
  274. *               interrupt routine state information - initial values set
  275.  
  276.         fdb     await           acia receiver state
  277.         fdb     asend           acia transmitter state
  278.         fdb     hkillb          hdlc receiver state
  279.         fdb     hsend           hdlc transmitter state
  280.         fdb     0               timer action state (after counted to zero)
  281.  
  282. *               i/o buffers
  283. *
  284. *       this is a circular buffer system, with the buffer extending from
  285. *       [FIRST] to [LIMIT-1].  IN is the real data in pointer.  When the
  286. *       block is accepted, AIN is updated to the value of IN.
  287.  
  288.  
  289.         FDB     cmdbuf,cmdbuf,cmdbuf,cmdbuf,cmdbuf+cmdsize
  290.  
  291. *       buffer from acia to hdlc
  292.         FDB     inbufend,inbufend,inbufend,inbufend,ram0end
  293.  
  294. *       buffer from hdlc to acia
  295.         FDB     inbuffer,inbuffer,inbuffer,inbuffer,inbufend
  296. inite2  equ     *
  297. initl2  equ     inite2-initv2
  298.  
  299. * next are buffer pointers if extra ram is installed.
  300. initv3  equ     *
  301. *       buffer from acia to hdlc
  302.         FDB     inbuffer,inbuffer,inbuffer,inbuffer,ram0end
  303.  
  304. *       buffer from hdlc to acia
  305.         FDB     ram1,ram1,ram1,ram1,ram1end
  306. inite3  equ     *
  307. initl3  equ     inite3-initv3
  308.  
  309. * interrupt re-vector area: parallel to fff0-ffff
  310.  
  311. jswi3   jmp     [iswi3]
  312. jswi2   jmp     [iswi2]
  313. jfirq   jmp     [ifirq]
  314. jirq    jmp     [iirq]
  315. jswi    jmp     [iswi]
  316. jnmi    jmp     [inmi]
  317. *
  318. * Initialize values for low core.
  319. * They MUST match the values they replace..
  320. *
  321. initv1  fdb     main            0000
  322.         fdb     main            0002
  323.         fdb     main            0004
  324.         fdb     action          0006
  325.         fdb     main            0008
  326.         fdb     main            000A - last vector used
  327. inite1  equ     *
  328. initl1  equ     inite1-initv1
  329.  
  330. ***             Main program
  331. *
  332. * First copy a default parameter block to ram.
  333. * Next setup our devices.
  334. * Finaly start playing and KISS.
  335. *
  336.  
  337.         setdp   $01
  338. main    orcc    #$50            turn off interrupts (FIRQ + IRQ)
  339.         lda     #1
  340.         tfr     A,DP            set base page register to our variables
  341.         lds     #stack          set stack to our local stack
  342.  
  343. *
  344. * move default values to low core !?????
  345. *
  346.         ldx    #$0000           desitination
  347.         ldy    #initv1
  348.         ldb    #initl1
  349. l_ini1  lda    0,y+
  350.         sta    0,x+
  351.         dec b
  352.         bne    l_ini1
  353. *
  354.         ldx    #$0100
  355.         ldy    #initv2
  356.         ldb    #initl2
  357. l_ini2  lda    0,y+
  358.         sta    0,x+
  359.         dec b
  360.         bne    l_ini2
  361.  
  362. *
  363. * test if extra ram is available
  364. *
  365.         ldd    #$aa55
  366.         std    ram1
  367.         lda    ram1
  368.         cmp a  #$aa
  369.         bne    main1         not there
  370.         lda    ram1+1
  371.         cmp a  #$55
  372.         bne    main1         faultly memory..
  373.  
  374. * move large buffer pointers to low core
  375.  
  376.         ldx    #abufh
  377.         ldy    #initv3
  378.         ldb    #initl3
  379. l_ini3  lda    0,y+
  380.         sta    0,x+
  381.         dec b
  382.         bne    l_ini3
  383.  
  384. * reset and disable UART
  385. main1   lda     a_speed         initialize from preset data
  386.         sta     acstat          reset device
  387.         ora     #$10            8 bit word, 1 stop, intern clock
  388.         sta     acctrl
  389.         lda     #ac_dis         turn off receiver, set RTS only
  390.         sta     accmnd
  391.  
  392. * reset 6520            Not used by this program
  393.         clra
  394.         sta     pcra            disable pia-A
  395.         sta     pcrb            disable pia-B
  396.  
  397. * reset 6522            NOVROM is not used, only timers are used
  398.         lda     #h_reset
  399.         sta     vpcr            clear CA2 to reset HDLC chip
  400.         lda     #t_cntl
  401.         sta     vacr            reset 6522 timer and shift register
  402.         lda     #$f0
  403.         sta     vora            set A output bits to '1'
  404.         sta     vddra            turning off NOVROM access
  405.         lda     #$bf
  406.         sta     vorb            set B output bits to '1'
  407.         sta     vddrb            driving NOVROM address to all 1's
  408.         lda     #$7f
  409.         sta     vier            disable all 6522 interrupts
  410.         sta     vifr            clear all 6522 interrupts
  411.         lda     #h_oper         clear HDLC reset bit, operate mode
  412.         sta     vpcr            reset 6522 control modes (CB2=1, CA2=1)
  413.  
  414.         pag
  415. *
  416. * preset
  417.         jsr     setdelay        compute delay counter values
  418.         lda     #CD             pretend CD set upon entry
  419.         sta      cdval
  420.  
  421. * setup hdlc chip
  422. * first, wait for at least 2.5 TC cycles...
  423.         ldb     #3*32           2.5 to 3 cycles
  424. pw_0    lda     vorb
  425.         bmi     pw_0            wait for 0
  426. pw_1    lda     vorb
  427.         bpl     pw_1            wait for 1 (1/2 cycle)
  428.         decb
  429.         bne     pw_0
  430.  
  431.         clra
  432.         sta      savhc
  433.         coma
  434.         sta     hcr3            no transmit residue
  435.         sta     hcr2            8-bit characters, no address comp
  436. **
  437.         lda     #ac_xmt         turn on acia, set RTS
  438.         sta     accmnd
  439.  
  440.         lda     #FEND           Send a first byte out
  441.         sta     acchar          to start this ballgame
  442.  
  443. pw_2    lda     #rcvon          start hdlc receiver
  444.         tst      fxflag
  445.         beq     hdon            half duplex
  446.         ldb     #fflags         turn on auto-flag
  447.         comb
  448.         stb     hcr2
  449.         ldx     #hfdxs
  450.         stx     HXMIT           state to begin full duplex ops
  451.         ldb     #1
  452.         stb      xmtok          transmit is always ok
  453.         ora     #actptt         activate ptt
  454. hdon    sta      savhc
  455.         coma
  456.         sta     hcr1
  457.  
  458.         jsr     hdsc            check current CD state
  459.  
  460.         cli                     TURN ON INTERRUPTS
  461.         pag
  462. ***             Main loop, non-interrupt mode
  463.  
  464. loop    ldy     #command        look for commands
  465.         jsr     getbuf
  466.         bne     lpax            no command
  467.         tab
  468.         cmpa    #FESC
  469.         bne     lp_b            Not an escaped char
  470.         jsr     getbuf          get escaped char
  471.         cmpa    #TFEND          is a FEND escaped ?
  472.         bne     lp_a
  473.         ldb     #FEND
  474.         bra     lp_b
  475. lp_a    cmpa    #TFESC
  476.         bne     lp_b            escape sequence error leave b as is.
  477.         ldb     #FESC
  478.  
  479. lp_b    jsr     getbuf          get second command byte
  480.         cmpa    #FESC
  481.         bne     lp_d            Not an escaped char
  482.         jsr     getbuf          get escaped char
  483.         cmpa    #TFEND          is a FEND escaped ?
  484.         bne     lp_c
  485.         lda     #FEND
  486.         bra     lp_d
  487. lp_c    cmpa    #TFESC
  488.         bne     lp_d            escape sequence error leave b as is.
  489.         lda     #FESC
  490. lp_d    sta     temp
  491.         jsr     getbuf          must be FEND
  492.         cmpa    #FEND
  493.         bne     badcmd          bad command, kill it
  494.         lda      temp
  495.  
  496. lp_1    decb                    tx delay
  497.         bne     lp_2
  498.         sta      u_txdly
  499.         bra     recomp          recompute delays
  500.  
  501. lp_2    decb                    persistence
  502.         bne     lp_3
  503.         sta      u_pers
  504.         bra     lpax
  505.  
  506. lp_3    decb                    slot time
  507.         bne     lp_4
  508.         sta      u_slot
  509.         bra     recomp
  510.  
  511. lp_4    decb                    tx tail
  512.         bne     lp_5
  513.         sta      u_tail
  514.         bra     recomp
  515.  
  516. lp_5    decb                    hdx/fdx
  517.         bne     lp_6
  518.         cmpa     fxflag         is this a change?
  519.         beq     lp_6            no
  520.         sta      fxflag
  521.         jmp     pw_2            jump to full / half check.
  522.  
  523. lp_6    decb                    baud rate and processor speed
  524.         bne     lpax            ..unrecognized
  525.         anda    #$7f            baud rate
  526.         sta      h_speed
  527.         lda      temp
  528.         anda    #$80            for TNC1 - fast processor flag
  529.         sta      p_speed
  530. recomp  jsr     setdelay        recompute delays and baud rate
  531.         bra     lpax
  532.  
  533. badcmd  jsr     getbuf          purge command buffer
  534.         bne     lpax            buffer empty
  535.         cmpa    #FEND
  536.         bne     badcmd
  537.  
  538. * if the acia is idle, but with interrupts enabled, the TXempty bit is 0
  539. * so we can't check that...
  540. lpax    lda     accmnd          is acia transmitter running
  541.         cmpa    #ac_xmt
  542.         beq     lpah            yes
  543.         ldy     #hbufa          is there data to send
  544.         ldx     AIN,Y
  545.         cpx     OUT,Y
  546.         beq     lpah            no
  547. **
  548.         sei                     turn off interrupts
  549.         lda     accmnd
  550.         cmpa    #ac_xmt
  551.         beq     lpac            cant start if acia running
  552.         jsr     [AXMIT]         start the acia transmitter
  553. lpac    cli                     turn on interrupts
  554. **
  555.  
  556. * check for transmit data to HDLC line in a similar fashion
  557. lpah    tst      xmtok          OK to go?
  558.         ble     lplp            no
  559.         ldy     #abufh
  560.         ldx     AIN,Y           is there data to send
  561.         cpx     OUT,Y
  562.         beq     lplp            no
  563. **
  564.         sei                     repeat test with interrupts off
  565.         tst      xmtok
  566.         ble     lpnh
  567.         ldy     #abufh
  568.         ldx     AIN,Y
  569.         cpx     OUT,Y
  570.         beq     lpnh
  571.         jsr     [HXMIT]         start the hdlc transmit process
  572. lpnh    cli                     turn interrupts back on
  573. **
  574.  
  575. lplp    jmp     loop
  576.         pag
  577.  
  578. ***     Interrupt Handler - main code
  579.  
  580. action  lda     acstat          first check for acia activity
  581.         bpl     chkh            none, check hdlc
  582.         bita    #as_rdr         is there any receive data
  583.         beq     chkax           no, check transmit
  584.  
  585.         jsr     [ARCV]          acia receive action
  586.         lda     acstat
  587.         bpl     chkh            no transmit action
  588.  
  589. chkax   bita    #as_xmt         is transmitter empty
  590.         beq     chkh            no
  591.  
  592.         jsr     [AXMIT]         acia transmitter action
  593.  
  594. chkh    lda     hir             HDLC interrupt register
  595.         coma
  596.         bita    #intrq
  597.         bne     chkh_1          upper bits are significant
  598.         anda    #drqo+drqi      only data bits are significant
  599.         beq     cktim           nothing, check timer
  600. chkh_1  sta      svhir          save it, since chip is now reset
  601.         bita    #drqi+reom+reomerr      is there receiver status
  602.         beq     chkhx           no receive action
  603.  
  604.         jsr     [HRCV]          perform receiver action
  605.         lda      svhir
  606.  
  607. chkhx   bita    #drqo+xcom+xcomerr      is there transmitter status
  608.         beq     chkhs           no transmitter action
  609.  
  610.         jsr     [HXMIT]         perform transmitter action
  611.         lda      svhir
  612.  
  613. chkhs   bita    #dscchg         data set change
  614.         beq     cktim           none, check timer
  615.  
  616.         jsr     hdsc            perform data set change action
  617.  
  618. cktim   lda     vifr            6522 interrupt flag register
  619.         bpl     xint            no timer interrupt
  620.  
  621.         jsr     dotime          handle timer
  622.  
  623. xint    rti                     exit interrupt main loop
  624.         pag
  625.  
  626. ***     Interrupt Action Routines
  627.  
  628. ***             ACIA receiver actions
  629.  
  630. gowait  ldy     #ARCV
  631.         jsr     xstate
  632.  
  633. await   equ     *               State - wait for FEND
  634.         ldb     acchar          read character
  635.         bita    #as_err         check for receiver errors
  636.         bne     cstate          yes, continue waiting (same state)
  637.         cmpb    #FEND           is this the start of a frame
  638.         bne     cstate          no, continue waiting (same state)
  639.  
  640. agetcom ldy     #ARCV           get block type byte
  641.         jsr     xstate          step state
  642.         ldb     acchar          read command character
  643.         bita    #as_err         check for receiver errors
  644.         bne     gowait          yes, resync on FEND
  645.         tstb                    is command 00
  646.         beq     agetdat         yes, get data
  647. dea     nop
  648.         cmpb    #FEND           extra FEND?
  649.         beq     cstate          yes, ignore it (stay in this state)
  650.         tba
  651.         ldy     #command
  652.         jsr     putbuf
  653.         bne     gowait          putbuf failed, ignore command, sorry!
  654.  
  655. abldcmd ldy     #ARCV           build command
  656.         jsr     xstate
  657.         ldy     #command        command buffer area
  658.         bra     abuild
  659.  
  660. cstate  rts                     stay in current state
  661.  
  662. agetdat ldy     #ARCV           get data
  663.         jsr     xstate
  664.         ldy     #abufh          data buffer area
  665.  
  666. abuild  ldb     acchar          read next byte
  667.         bita    #as_err         check for receiver errors
  668.         bne     adumpc          yes, dump data gathered so far
  669.         tba
  670.         jsr     putbuf          add byte to buffer
  671.         bne     adumpc          putbuf failed, dump data
  672.         cmpa    #FEND           last byte?
  673.         bne     cstate          no, continue to gather data
  674.         ldx     IN,Y            accept data
  675.         stx     AIN,Y
  676.         bra     agetcom         next byte should be command again
  677.  
  678. adumpc  ldx     AIN,Y           dump accumulation of data
  679.         stx     IN,Y
  680.         cmpa    #FEND           was failure on last byte
  681.         bne     gowait          no, wait for FEND
  682.         bra     agetcom         yes, get command again
  683.         pag
  684.  
  685.  
  686. ***             ACIA transmitter actions
  687.  
  688. axsend  ldy     #AXMIT
  689.         jsr     xstate
  690. asend   equ     *               Transmitter active on entry
  691.         ldy     #hbufa
  692.         jsr     getbuf          get next character to send to host
  693.         bne     axnone          none, turn off transmit
  694.         sta     acchar          send the char
  695.         rts                     stay in this state
  696.  
  697. axnone  lda     #ac_enb         turn off transmit interrupts
  698.         sta     accmnd
  699.         ldy     #AXMIT
  700.         jsr     xstate
  701.  
  702.         ldy     #hbufa          attempt to restart transmitter
  703.         jsr     getbuf
  704.         bne     cstate          no character, dont start
  705.         ldb     #ac_xmt         re-enable interrupt
  706.         stb     accmnd
  707.         sta     acchar          send the character
  708.         bra     axsend          flip to other state
  709.         pag
  710.  
  711.  
  712. ***             HDLC receive actions
  713.  
  714. hkillb  ldy     #hbufa          kill receive block
  715.         ldx     AIN,Y
  716.         stx     IN,Y
  717. *
  718. * initialize the header for KISS frame
  719. *
  720. gohrec  lda     #FEND           Frame delimiter first
  721.         jsr     putbuf
  722.         clra                    next byte indicates DATA block
  723.         sta     bdblk           clear bad block flag
  724.         jsr     hputbuf
  725.  
  726.         ldy     #HRCV
  727.         jsr     xstate
  728.  
  729. hrec    equ     *               receive characters here
  730.         bita    #drqi           do we have a character
  731.         beq     hrckend         no, check end cases
  732.         ldy     #hbufa          receive buffer
  733.         lda     hrhr            receive character
  734.         coma
  735.         cmpa    #FEND           check special cases
  736.         beq     hrec_1
  737.         cmpa    #FESC
  738.         bne     hrec_2          ordinary character
  739.         ldb     #TFESC
  740.         bra     hrec_1a
  741. hrec_1  ldb     #TFEND
  742. hrec_1a lda     #FESC
  743.         jsr     hputbuf         put character in buffer
  744.         tba
  745. hrec_2  jsr     hputbuf         put character in buffer
  746.         lda     svhir
  747.         bita    #reom           was this also end of message
  748.         bne     hreom
  749.         bita    #reomerr        was this also an error end
  750.         bne     hkillb
  751.         rts                     continue (stay in this state)
  752.  
  753. hrckend bita    #reom           normal end
  754.         beq     hkillb          no, kill receive block
  755.  
  756. * The WD chip has read in the bcc before giving us the eom indication.
  757. *  We must back over it
  758.  
  759. hreom   ldy     #hbufa
  760.         jsr     back2           back up 2 characters
  761.         bne     hkillb          (system) error in backing
  762.         lda     #FEND
  763.         jsr     hputbuf
  764.         tst     bdblk           check for a valide frame (no errors)
  765.         bne     hkillb          buffer full
  766.         ldx     IN,Y            accept data
  767.         stx     AIN,Y
  768.         bra     gohrec          set to receive next block
  769.         pag
  770.  
  771.  
  772. ***             HDLC transmit actions
  773.  
  774. gohsend ldy     #HXMIT
  775.         jsr     xstate
  776.  
  777. hsend   equ     *               initial transmit state
  778.         lda     #-1             signal transmit active
  779.         sta      xmtok
  780.         tst      fxflag         is this full duplex
  781.         bne     hstart          yes, start sending immediately
  782.         lda      savhc
  783.         anda    #NOT-actrcv     turn off receiver if half duplex
  784.         sta      savhc
  785.         lda     #2
  786.         sta     bdblk           abort any partial block received
  787.         ldx      c_txdly        pre-xmit delay
  788.         beq     hstart          no delay
  789.         clra                    pre-start, send zeros for sync
  790.         coma                     (this gives faster DPLL lockup)
  791.         sta     hthr
  792.         lda     #h_data         send data
  793.         jsr     setcr1
  794.         ldd      c_txdly        start timer
  795.         ldx     #hset1
  796.         jsr     settime
  797.  
  798.         ldy     #HXMIT          pre-start state, just send more zeros
  799.         jsr     xstate
  800.         bita    #drqo           check for normal entry
  801.         lbeq    hxabt           abort, abnormal termination
  802.         clra
  803.         coma
  804.         sta     hthr            send another zero
  805.         rts                     stay in this state until timer runs out
  806.  
  807. **
  808. hset1   ldx     #hstart         Timer action: start block
  809.         stx     HXMIT
  810.         rts
  811. **
  812.  
  813. hstart  ldy     #abufh
  814.         jsr     getbuf          get first character of frame
  815.         coma
  816.         sta     hthr             this prevents DRQO interrupts...
  817.         tst      fxflag         is this full duplex
  818.         bne     hsdat           yes, can go immediately
  819.         lda     #h_flag         if half duplex, send leading flag
  820.         bra     hsgo
  821.  
  822. hfdxs   lda     #-1             initial full duplex start
  823.         sta      xmtok
  824.         lda      savhc
  825.         ora     #actran         turn on transmitter..
  826.         sta      savhc
  827.         coma
  828.         sta     hcr1
  829.         bra     hsendc          wait for DRQO and start
  830.  
  831. hendf   lda     #h_fcs          send fcs + done
  832.         bra     hxab_E
  833.  
  834. hfcs    jsr     getbuf          is there another frame
  835.         bne     hendf           no
  836.         cmpa    #FEND           is this a null frame
  837.         beq     hfcs            yes, skip it
  838.         coma
  839.         sta     hthr            load first character of next frame..
  840.         lda     #h_fcs
  841.  
  842. hsgo    jsr     setcr1          send flag or fcs before frame
  843.  
  844.         ldy     #HXMIT
  845.         jsr     xstate          set next state
  846.  
  847.         bita    #xcom
  848.         beq     hxabt           abort on error
  849. hsdat   lda     #h_data         put us into data mode for frame
  850.         jsr     setcr1           (first character goes now...)
  851.  
  852.         ldy     #HXMIT
  853.         jsr     xstate
  854.  
  855. hscont  ldy     #abufh
  856.         jsr     getbuf          get next character
  857.         bne     hxab_H          out of data, without FEND (internal error)
  858.         cmpa    #FESC           escape
  859.         bne     hsenda          ordinary character
  860.         jsr     getbuf          get character following FESC
  861.         tab
  862.         lda     #FEND
  863.         cmpb    #TFEND
  864.         beq     hsendb
  865.         lda     #FESC           these are all of the cases (today)
  866.         cmpb    #TFESC
  867.         beq     hsendb
  868.         tba                     recover character, invalid escape
  869. hsenda  cmpa    #FEND
  870.         beq     hfcs            done, send fcs
  871. hsendb  coma
  872.         sta     hthr            send character
  873.  
  874. hsendc  ldy     #HXMIT
  875.         jsr     xstate          set next state
  876.  
  877.         bita    #xcomerr        error sending
  878.         beq     hscont          continue if no error
  879.  
  880. hxabt   ldy     #abufh          error sending, scrap entire message
  881. hxab_1  jsr     getbuf
  882.         bne     hxab_H
  883.         cmpa    #FEND
  884.         bne     hxab_1
  885. hxab_H  lda     #h_abort
  886.  
  887. hxab_E  jsr     setcr1          send the abort or fcs at end
  888.  
  889.         ldy     #HXMIT
  890.         jsr     xstate
  891.  
  892.         ldd      c_tail         post-xmit timer
  893.         beq     hxdone          no waiting
  894.         ldx     #hxdone
  895.         jsr     settime         start tail timer
  896.         ldy     #HXMIT
  897.         jsr     xstate
  898.  
  899.         clra
  900.         coma
  901.         sta     hthr            make DRQO interrupts go away
  902.         rts                     return - no interrupts until timer done
  903.  
  904. hxdone  lda     #1              not transmitting
  905.         sta      xmtok
  906.         tst      fxflag         full duplex?
  907.         bne     hxd_1           yes, don't turn off ptt
  908.  
  909.         lda      savhc
  910.         anda    #NOT-actran-actptt      turn off transmitter
  911.         ora     #actrcv         turn on receiver
  912.         sta      savhc
  913.         coma
  914.         sta     hcr1
  915.         clr      xmtok          receiving flag
  916.         lda     #CD
  917.         sta      cdval          re-examine CD state
  918.         bsr     hdsc
  919.  
  920. hxd_1   jmp     gohsend         return to starting state
  921.         pag
  922.  
  923.  
  924. ***             Carrier-sense change handler
  925.  
  926. hdsc    lda     hsr             read status register
  927.         tst      fxflag         are we full duplex?
  928.         bne     hdrts           yes, no action needed
  929.         coma
  930.         anda    #CD             look at CD bit
  931.         cmpa     cdval          compare with saved value
  932.         beq     hdrts           same, no action
  933.         sta      cdval          save new value
  934.         beq     hdsoff          now off
  935.  
  936. hdson   tst      xmtok          hdx - are we transmitting now?
  937.         bmi     hdrts           yes, will turn on at end of xmit
  938.         clr      xmtok          set state to receiving
  939.         lda     #v_int
  940.         sta     vier            disable timer2 interrupt, if active
  941.         ldd     timer2
  942. hdrts   rts                     return
  943.  
  944. hdsoff  tst      xmtok          are we transmiting?
  945.         bne     hdrts           yes, if half duplex this is false indication
  946.         bra     pwait           always wait 1 slot time at least...
  947.  
  948. persist jsr     getran          get a random number
  949.         cmpb     u_pers         compare against persistence value
  950.         bls     setxok          ok to transmit
  951. pwait   ldd      c_slot         no, wait 'slot' time and retry
  952.         ldx     #persist
  953.         bra     settime         start timer
  954.  
  955. setxok  lda     #1              ok to transmit now
  956.         sta      xmtok
  957.         rts
  958.         pag
  959.  
  960.  
  961. ***             Timer handling
  962.  
  963. dotime  ldd     timer2          clear timer interrupt and read timer
  964.         tst      upper_t
  965.         beq     tdone           timer expired
  966.         dec      upper_t
  967.         tsta
  968.         bne     dot_1           correct for nn00 to (nn-1)ff
  969.         incb
  970. dot_1   std     timer2          reenable interrupt
  971.         rts                     done with timer
  972.  
  973. tdone   lda     #v_int          timer2 interrupt bit
  974.         sta     vier            disable interrupt
  975.         lda     timer2
  976.         jmp     [TIMACT]        do timer action
  977.         pag
  978.  
  979.  
  980. ***     Interrupt Support Subroutines
  981.  
  982. * SETCR1 - set type of transmit in hcr1 - done often
  983. *
  984. *       entry:  A = new data/flag/abort type to set
  985. setcr1  sta      tempih
  986.         lda      savhc
  987.         anda    #h_MASK
  988.         ora      tempih
  989.         sta      savhc
  990.         coma
  991.         sta     hcr1
  992.         rts
  993.  
  994. * SETTIME - start timer with specified action
  995. *
  996. *       entry:  D = upper 16 bits of 24 bit timer value
  997. *               X = location of timer action routine
  998. *
  999. settime stx     TIMACT          store action address
  1000.         sta      upper_t        upper 8 bit of timer value
  1001.         clra
  1002.         tstb                    is timer value 0 mod 65536
  1003.         bne     sett_1          no
  1004.         dec      upper_t        yes, tick over one count
  1005.         bmi     tdone           all zero count, finish immediately
  1006.         coma
  1007.         comb                    set D = $ffff
  1008. sett_1  std     timer2          start timer with residual mod 65536
  1009.         lda     #vs_int         enable timer2 interrupt
  1010.         sta     vier
  1011.         rts
  1012.  
  1013. * XSTATE - set new state for interrupt task
  1014. *
  1015. *       entry:  address of state jump word in Y
  1016. *
  1017. xstate  puls    X               get return address into X
  1018.         stx     0,Y             save it as state address
  1019.         rts                     return to state caller
  1020.         pag
  1021.  
  1022.  
  1023. ***     General Subroutines
  1024.  
  1025. * GETBUF, PUTBUF - handle getting or putting characters from/to buffers
  1026. *
  1027. *       entry:  buffer head address in Y
  1028. *       exit:   zero flag set if all is well, NZ otherwise (overflow or empty)
  1029. *
  1030. getbuf  ldx     OUT,Y           get the OUT pointer
  1031.         cpx     AIN,Y           check for data present
  1032.         beq     nobuf           no data, set NZ and exit
  1033.         lda     0,X             get the data
  1034.         bsr     incbuf          increment pointer value
  1035.         stx     OUT,Y           new pointer
  1036. yesbuf  orcc    #CCZ            set Z flag
  1037.         rts
  1038.  
  1039. putbuf  ldx     IN,Y            get the IN pointer
  1040.         tfr     X,U             save it in a convenient place
  1041.         bsr     incbuf          next value of IN
  1042.         cpx     OUT,Y           is the buffer full
  1043.         beq     nobuf           yes, operation fails
  1044.         sta     0,U             no, store the data
  1045.         stx     IN,Y            new pointer
  1046.         bra     yesbuf
  1047.  
  1048. nobuf   andcc   #CCNZ           clear Z flag
  1049.         rts
  1050.  
  1051. incbuf  inx                     increment pointer
  1052.         cpx     LIMIT,Y         at limit
  1053.         bne     incrts          no
  1054.         ldx     FIRST,Y         yes, wrap to first
  1055. incrts  rts
  1056.  
  1057. *
  1058. * HPUTBUF - like putbuf, but sets bdblk if put failed
  1059. *
  1060. hputbuf bsr     putbuf          go put in buffer
  1061.         beq     hputrts         OK just return
  1062.         lda     #1              abort frame flag
  1063.         sta     bdblk
  1064. hputrts rts
  1065.  
  1066. * BACK2 - back up in buffer -- used to back up over bcc received
  1067. *
  1068. *       entry:  buffer head address in Y
  1069. *
  1070. *  A good block should leave at least 2 data characters plus the bcc
  1071. *   in the buffer.  The backup algorithm takes advantage of this
  1072. *   when over-backing to check for FESC
  1073. *
  1074.  
  1075. back2   ldx     IN,Y
  1076.         cpx     AIN,Y
  1077.         beq     nobuf           whoops.. shouldn't happen (system error)
  1078.         bsr     back1
  1079.         bne     incrts          error
  1080.         bsr     back1
  1081.         bne     incrts          error
  1082.         stx     IN,Y
  1083.         bra     yesbuf          no error
  1084.  
  1085. back1   bsr     decbuf          back up
  1086.         bne     incrts          hit old AIN
  1087.         bsr     decbuf
  1088.         bne     incrts
  1089.         lda     0,X
  1090.         cmpa    #FESC
  1091.         beq     yesbuf          2 back was FESC, so 1 back was escaped
  1092.         bsr     incbuf          1 back was good
  1093.         bra     yesbuf
  1094.  
  1095. decbuf  cpx     FIRST,Y
  1096.         bne     decb_1
  1097.         ldx     LIMIT,Y
  1098. decb_1  dex
  1099.         cpx     AIN,Y
  1100.         bne     yesbuf          ok, not at AIN
  1101.         bra     nobuf           whoops.. shouldn't happen (system error)
  1102.  
  1103. * GETRAN - get a random number in B
  1104. *
  1105. *       uses mixed congruential generator: X' = 21*X + 53
  1106. *
  1107. getran  lda     #21
  1108.         ldb      rand           previous value
  1109.         mul
  1110.         addb    #53
  1111.         stb      rand
  1112.         rts
  1113.  
  1114. * SETDELAY - compute delay values and set baud rate counter
  1115. *
  1116. setdelay ldb    #36             = 921600 / 256 (* .01 seconds)
  1117.         tst      p_speed        is this a fast processor/counter
  1118.         beq     _setd1          no
  1119.         aslb                    yes, double the count required
  1120. _setd1  stb      temp
  1121.         lda      u_txdly        units of tx delay
  1122.         mul
  1123.         std      c_txdly
  1124.         ldb      temp
  1125.         lda      u_slot         units of slot delay
  1126.         mul
  1127.         std      c_slot
  1128.         ldb      temp
  1129.         lda      u_tail         units of tx tail delay
  1130.         mul
  1131.         std      c_tail
  1132.  
  1133.         tst      h_speed        speed requested for hdlc
  1134.         bne     _seth1          legal speed requested
  1135.         lda     #4              default to 1200 on error
  1136.         sta      h_speed
  1137. _seth1  ldb     #96             = 300 baud at fast processor clock
  1138.         clra
  1139. _seth2  inca
  1140.         subb     h_speed
  1141.         bgt     _seth2          divide 96 by multiple of 300 baud desired
  1142.         tst      p_speed        now check processor speed
  1143.         bne     _seth3          fast
  1144.         lsra                    slow, divide result by 2
  1145. _seth3  suba    #2              counter always takes 2 more per half cycle
  1146.         bmi     _seth4          too fast, ignore request
  1147.         clrb
  1148.         std     timrc1          store baud rate in timer 1 COUNTER to start it
  1149. _seth4  rts
  1150.  
  1151.  
  1152.         fcc     'TNC-1 KISS firmware WB6ECE, PA0GRI 22 dec 1987'
  1153.  
  1154.         end
  1155.  
  1156.